# -*- coding:utf8 -*-
import json
import traceback
import os
import re
import typing
from scrapy import Request, FormRequest
from squirrel_core.commons.utils.tools import calc_str_md5, upload_file
from squirrel_core.frame.spider_makaka import MakakaSpider

file_path = os.environ.get("FILE_PATH", "/")


class xtibo_score(MakakaSpider):
    name = "xtibo_score"
    serialNumber = ""
    header = {
        "Host": "rs-score.xtibo.com",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
    }

    def get_ext_requests_or_urls(self, data=None):
        if data and isinstance(data, str):
            data = json.loads(data)
        if data and isinstance(data, typing.MutableMapping):
            self.serialNumber = data.get("serialNumber", "")
            race_id = data.get("spider_config", {}).get("race_id", "")
            user_id = data.get("spider_config", {}).get("user_id", "")
            race_no = data.get("spider_config", {}).get("race_no", "")
            user_name = data.get("spider_config", {}).get("user_name", "")
            card_num = data.get("spider_config", {}).get("card_num", "")
            race_name = data.get("spider_config", {}).get("race_name", "").replace(" ", "")
            home_url = data.get("spider_config", {}).get("url", "")
            if not home_url and not card_num:
                self.logger.info("url和card_num必须存在")
                self.upload_procedure({"serialNumber": self.serialNumber, "code": 203, "message": "url和card_num必须存在"})
                self.close_after_idle = True
                self.force_to_close_spider = True
            else:
                self.upload_procedure({"serialNumber": self.serialNumber, "code": 100, "message": "任务启动成功"})
                if "www.tccscn.com" in home_url:
                    event_id = "".join(re.findall(r"gi=(\d+)", home_url))
                    url = f"http://www.tccscn.com/marathon/QuaryScore/Serch?gi={event_id}&bib={card_num}"
                    yield Request(url=url, callback=self.parse_tccscn, dont_filter=True, errback=self.err_parse,
                                  meta={"race_id": race_id, "user_id": user_id, "user_name": user_name,
                                        "race_name": race_name, "card_num": card_num, "race_no": race_no})
                elif "#小程序://去撒野" in home_url:
                    token = "2d6e9bb4-ae69-40be-9f9e-53b4e86a29f7"
                    url = "https://qsy.ucs-intertech.com/index.php/api/ygame/result/search"
                    header = {
                        "Host": "qsy.ucs-intertech.com",
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x6309092b)XWEB/14315",
                        "token": token,
                        "Content-Type": "application/x-www-form-urlencoded",
                        "Accept": "*/*"
                    }
                    post_data = {"name": user_name, "idcard": card_num}
                    yield FormRequest(url=url, callback=self.parse_saye, dont_filter=True, errback=self.err_parse, headers=header,
                                      formdata=post_data, meta={"race_id": race_id, "user_id": user_id,
                                                                "user_name": user_name, "race_name": race_name,
                                                                "card_num": card_num, "race_no": race_no, "header": header})
                else:
                    event_id = "".join(re.findall(r"(\d+)", home_url))
                    url = f"https://rs-score.xtibo.com/cert/race/detail/{event_id}/{card_num}"
                    yield Request(url=url, callback=self.parse, dont_filter=True, errback=self.err_parse, headers=self.header,
                                  meta={"race_id": race_id, "user_id": user_id, "user_name": user_name,
                                        "race_name": race_name, "card_num": card_num, "race_no": race_no})

    def parse(self, response, **kwargs):
        race_id = response.meta.get("race_id", "")
        user_id = response.meta.get("user_id", "")
        race_name = response.meta.get("race_name", "")
        user_name = response.meta.get("user_name", "")
        race_no = response.meta.get("race_no", "")
        try:
            self.logger.info(f"开始解析赛事信息:{response.url}")
            content_str = "".join(re.findall(r"var field = (.*?);", response.text)).strip()
            if content_str:
                content = json.loads(content_str)
                score_data = {"race_name": race_name, "itemName": content.get("cmptGroup", ""),
                              "name": content.get("field1", user_name), "raceNo": content.get("plateNo", race_no), "pace": content.get("field7", ""),
                              "distance": "", "shotScore": content.get("field5", ""), "score": content.get("field6", "")}
                cert_url = content.get("certUrl", "")
                if cert_url:
                    yield Request(url=cert_url, callback=self.parse_pic, errback=self.err_parse, dont_filter=True,
                                  meta={"race_id": race_id, "race_no": race_no, "user_id": user_id,
                                        "score_data": score_data})
                else:
                    result = self.result_item_assembler(response)
                    result['result_data'] = {"serialNumber": self.serialNumber, "webType": self.name_first,
                                             "crawlerType": self.name_second, "data": str(score_data)}
                    yield result
        except Exception:
            self.logger.info(f"解析赛事信息时出错{response.url}：{traceback.format_exc()}")

    def parse_tccscn(self, response, **kwargs):
        race_id = response.meta.get("race_id", "")
        user_id = response.meta.get("user_id", "")
        race_name = response.meta.get("race_name", "")
        user_name = response.meta.get("user_name", "")
        race_no = response.meta.get("race_no", "")
        try:
            self.logger.info(f"开始解析{user_name}的证书链接")
            score_data = {"race_name": race_name, "itemName": "", "name": user_name, "raceNo": race_no, "pace": "",
                          "distance": "", "shotScore": "", "score": ""}
            cert_link = "".join(response.xpath("//img[@id='im']/@src").extract()).strip()
            if cert_link:
                cert_link = cert_link.strip("..").split("?")[0]
                cert_url = f"http://www.tccscn.com/marathon{cert_link}"
                yield Request(url=cert_url, callback=self.parse_pic, errback=self.err_parse, dont_filter=True,
                              meta={"race_id": race_id, "race_no": race_no, "user_id": user_id,
                                    "score_data": score_data})
            else:
                result = self.result_item_assembler(response)
                result['result_data'] = {"serialNumber": self.serialNumber, "webType": self.name_first,
                                         "crawlerType": self.name_second, "data": str(score_data)}
                yield result
        except Exception:
            self.logger.info(f"解析赛事信息时出错{response.url}：{traceback.format_exc()}")

    def parse_saye(self, response, **kwargs):
        race_id = response.meta.get("race_id", "")
        user_id = response.meta.get("user_id", "")
        race_name = response.meta.get("race_name", "")
        user_name = response.meta.get("user_name", "")
        race_no = response.meta.get("race_no", "")
        header = response.meta.get("header", "")
        try:
            self.logger.info(f"开始解析{user_name}的成绩信息")
            data_list = json.loads(response.text).get("data", {}).get("data", [])
            if data_list:
                for data in data_list:
                    score_data = {"race_name": data.get("project_name", race_name), "itemName": data.get("group", ""),
                                  "name": user_name, "raceNo": race_no,
                                  "pace": "", "distance": "", "shotScore": "", "score": data.get("result", "")}
                    _id = data.get("id", "")
                    if _id:
                        cert_url = "https://qsy.ucs-intertech.com/index.php/api/ygame/result/cert"
                        post_data = {"result_id": str(_id)}
                        yield FormRequest(url=cert_url, callback=self.parse_saye_cert, dont_filter=True,
                                          errback=self.err_parse, headers=header, formdata=post_data,
                                          meta={"race_id": race_id, "user_id": user_id, "score_data": score_data,
                                                "user_name": user_name, "race_name": race_name, "race_no": race_no})
                    else:
                        result = self.result_item_assembler(response)
                        result['result_data'] = {"serialNumber": self.serialNumber, "webType": self.name_first,
                                                 "crawlerType": self.name_second, "data": str(score_data)}
                        yield result
            else:
                result = self.result_item_assembler(response)
                result['result_data'] = {"serialNumber": self.serialNumber, "webType": self.name_first,
                                         "crawlerType": self.name_second, "data": str({"msg": "未查到相关成绩信息"})}
                yield result
        except Exception:
            self.logger.info(f"解析{user_name}的成绩信息时出错{response.url}：{traceback.format_exc()}")

    def parse_saye_cert(self, response, **kwargs):
        race_id = response.meta.get("race_id", "")
        user_id = response.meta.get("user_id", "")
        race_name = response.meta.get("race_name", "")
        user_name = response.meta.get("user_name", "")
        race_no = response.meta.get("race_no", "")
        score_data = response.meta.get("score_data", {})
        try:
            self.logger.info(f"开始解析{user_name}的证书链接")
            url = json.loads(response.text).get("data", "")
            if url:
                yield Request(url=url, callback=self.parse_pic, errback=self.err_parse, dont_filter=True,
                              meta={"race_id": race_id, "race_no": race_no, "user_id": user_id,
                                    "score_data": score_data})
            else:
                result = self.result_item_assembler(response)
                result['result_data'] = {"serialNumber": self.serialNumber, "webType": self.name_first,
                                         "crawlerType": self.name_second, "data": str(score_data)}
                yield result
        except Exception:
            self.logger.info(f"解析{user_name}的证书链接时出错{response.url}：{traceback.format_exc()}")

    def parse_pic(self, response):
        race_id = response.meta.get("race_id", "")
        user_id = response.meta.get("user_id", "")
        race_no = response.meta.get("race_no", "")
        score_data = response.meta.get("score_data", {})
        try:
            self.logger.info(f"开始下载{race_no}的证书：{response.url}")
            pic_md5 = calc_str_md5(response.url)
            pic_name = f"{race_no}_{pic_md5}.jpg"
            dir_path = os.path.join(file_path, "picture", self.name_first)
            if not os.path.exists(dir_path):
                os.makedirs(dir_path)
            save_path = os.path.join(dir_path, pic_name)
            if not os.path.exists(save_path):
                with open(save_path, "wb") as f:
                    f.write(response.body)
                upload_path = f"flow/{race_id}/{user_id}/pic/{pic_name}"
                upload_flag = upload_file(save_path, upload_path)
                if upload_flag:
                    self.logger.info(f"{save_path}上传成功：{upload_path}")
                else:
                    self.logger.info(f"{save_path}上传失败：{upload_path}")
                score_data["certImg"] = upload_path
                result = self.result_item_assembler(response)
                result['result_data'] = {"serialNumber": self.serialNumber, "webType": self.name_first,
                                         "crawlerType": self.name_second, "data": str(score_data)}
                yield result
        except Exception:
            self.logger.info(f"下载{race_no}证书时出错{response.url}：{traceback.format_exc()}")

    def err_parse(self, failure):
        self.logger.warning(f"请求失败：{failure.request.url},错误原因:{traceback.format_exc()}")

